#include "lector.h"

#include "funcionesSueltas.h"
#include "NGramas.h"
#include <iostream>
#include <cstring>
#include <stdlib.h>
#include <stdio.h>
#include <set>
#include <locale>
#define NOMBRE_TRAIN_SET "train_v2.txt"
//#define NOMBRE_TRAIN_SET "train_de_prueba.txt"

//extern map<string,sFreqArchivo> diccionario;
extern map<string,datosDeUnaPAlabraDelDiccionario> diccionarioCompleto;



int fragmentoUsado = -1;
set<string> palabrasAparecidasEnElFragmento;

map<string, ofstream*> mapaPalabraArchivoDeApariciones;

map<string, set<int>*> mapa;

/*
bool yaAparecioEnFragmento(string palabra, int fragmento){

	FILE* file = abrirApariciones(palabra, "r");
	if (file != NULL){
		while(!feof(file))
			if( obtenerAparicion(file) == fragmento)
				return true;
	}
	return false;
}
*/

bool yaAparecioEnFragmento(string palabra){

	if ( palabrasAparecidasEnElFragmento.find(palabra) == palabrasAparecidasEnElFragmento.end() ){
		//Si es T entonces la palabra no se encontro
		palabrasAparecidasEnElFragmento.insert(palabra);
		return false;
	}
	else{
		return true;
	}

}










void agregarAparicion(string palabra, int fragmento){


	//if(palabra == "Tevez"){printf("Tevez entro en agregar aparicion\n");}

	//if (mapaPalabraArchivoDeApariciones.find(palabra) == mapaPalabraArchivoDeApariciones.end() ){
	//	string fileName;
	//	fileName = "apariciones/apariciones_de_";
	//	fileName += palabra;
	//	fileName += ".txt";

	///*	if(palabra == "Tevez"){
	//		printf("Se creo el archivo de Tevez\n");
	//		fileName = "el_apache_Tevez.txt";
	//	}
	//*/

	//	ofstream* archivoDeApariciones = new  ofstream;
	//	archivoDeApariciones->open(fileName.c_str(), ios::app);
	//
	//	mapaPalabraArchivoDeApariciones[palabra] = archivoDeApariciones;
	//}
	//
	//
	//(*mapaPalabraArchivoDeApariciones[palabra])<<fragmento<<"\n";


//SE CAMBIA A DICCIONARIO COMPLETO
/*	if (mapa.find(palabra) == mapa.end() ){
		mapa[palabra] = new set<int>;
	}
	mapa[palabra]->insert(fragmento);
*/
	//ANTES SE DEBEN CARGAR LAS PALABRASS
	diccionarioCompleto[palabra].apariciones->insert(fragmento);

}


void guardarArchivosDeAparicion(){

/////////////////////ARCHIVOS INDIVIDUALES CON FILTRO //////////////////////
/*	for( map<string,set<int>*>::iterator iterador = mapa.begin() ; iterador != mapa.end(); ++iterador){
		if (mapa[(*iterador).first]->size() > 3){
			string fileName;
			fileName = "apariciones/apariciones_de_";
			fileName += (*iterador).first;
			fileName += ".txt";


			ofstream archivoDeApariciones;
			archivoDeApariciones.open(fileName.c_str(), ios::app);


			for (set<int>::iterator iteradorSet = mapa[(*iterador).first]->begin(); iteradorSet != mapa[(*iterador).first]->end(); ++iteradorSet){
				archivoDeApariciones<<(*iteradorSet)<<"\n";
			}

			delete mapa[(*iterador).first];
		}
	}
*/
///////////////VERSION TODO EN UN MISMO ARCHIVO CON FILTRO/////////////////////////
	string fileName;
	fileName = "apariciones/apariciones.txt";
	ofstream archivoDeApariciones;
	archivoDeApariciones.open(fileName.c_str(), ios::app);
	for( map<string,set<int>*>::iterator iterador = mapa.begin() ; iterador != mapa.end(); ++iterador){
		//por cada palabra recorro su set de apariciones
		if (mapa[(*iterador).first]->size() > 3){
			archivoDeApariciones<<(*iterador).first<<" ";
			for (set<int>::iterator iteradorSet = mapa[(*iterador).first]->begin(); iteradorSet != mapa[(*iterador).first]->end(); ++iteradorSet){
				archivoDeApariciones<<(*iteradorSet)<<" ";
			}

			archivoDeApariciones<<"$ \n";
			delete (*iterador).second;
		}
	}
	archivoDeApariciones.close();


}








//El & es para pasalo por referencia, si no se pasar�a por valor y perder�a tiempo copiando el vector
void agregarApariciones(vector<string> &vectorDePalabras, int fragmentoActual){

	if ( fragmentoActual != fragmentoUsado ){
		palabrasAparecidasEnElFragmento.clear();
		fragmentoUsado = fragmentoActual;
	}

	string palabra;
	size_t tam = vectorDePalabras.size();
	for(size_t i = 0; i < tam; i++){
		palabra = vectorDePalabras.at(i);

		if( !yaAparecioEnFragmento(palabra) ){
			agregarAparicion(palabra, fragmentoActual);
		}
	}
}

bool palabraTerminaEnPunto(string palabra){

	if ( (*palabra.rbegin()) == '.' ){
		return true;
	}
	else {
		return false;
	}
}












void aprender(){

	string fileName = NOMBRE_TRAIN_SET;
	ifstream train;
	train.open(fileName.c_str());
	string palabra;

	vector<string> vectorDeFrase;
	int fragmentoActual;


	if(train.is_open()){
		while(train >> palabra &&  (train.tellg()<500000)){

			if ( palabraTerminaEnPunto(palabra) ){

				vectorDeFrase.push_back(palabra);


				//Debug de frase
				//	size_t tam = vectorDeFrase.size();
				//	for(size_t i = 0; i < tam; i++){
				//		cout<<vectorDeFrase.at(i)<<" ";
				//	}
				//
				//	printf("\n");
				//Fin debug


				fragmentoActual = train.tellg()/23000;

				agregarTrigramas(vectorDeFrase);
				agregarApariciones(vectorDeFrase, fragmentoActual);



				vectorDeFrase.clear();
			}
			else{
				vectorDeFrase.push_back(palabra);
			}
		}

		cout<<"El ultimo punto de lectura fue: "<<train.tellg()<<"\n";

		train.close();
	}
}






void cerrarArchivosDeApariciones(){
	for( map<string,ofstream*>::iterator iterador = mapaPalabraArchivoDeApariciones.begin() ; iterador != mapaPalabraArchivoDeApariciones.end(); ++iterador){
		if ((*iterador).second != nullptr ){
			(*iterador).second->close();
			delete (*iterador).second;
		}
	}
}
